<?php

class Workset_Filter_StringSplit implements Zend_Filter_Interface {

    protected $_options = array(
        'length' => 255,
        'end' => '...',
    );

	public function __construct($options = null) {
    	if ($options !== null) {
			$this->setOptions($options);
		}
    }

    /**
     * @param  array $options
     * @return void
     */
	public function setOptions($options) {
        $options = (array)$options;

		if (count($options) == 1 && isInt(key($options))) {
			$options = array(
				'length' => (int)current($options),
			);
		}

		$this->_options = array_merge($this->_options, $options);
	}

    /**
     * Обрезает строку по указанной длине с учетом окончаний слов и
     * знаков пунктуации.
     *
     * @param  $value
     * @return string
     */
    public function filter($value) {

        $value = (string)$value;

        $endLength = strlen($this->_options['end']);
        $length = $this->_options['length'] - $endLength;

        if ($length < 1) {
            $length = $endLength;
        }

        if (strlen($value) <= $length) {
            return $value;
        }

        $end = true;

        $i = 10;

        while ($i-- > 0)  {

            $part = preg_replace('/^(.{0,'.$length.'}).*?$/us', '$1', $value);

            $checkPart = trim($part);

            $str = substr($value, strlen($part));

            //окончание/середина слова
            if (preg_match('/([\pL\pN]+)$/u', $checkPart, $matches1)) {
                if (preg_match('/^([\.\!\?]+)/u', $str, $matches2)) {
                    if (strlen($matches2[1]) > $endLength) {
                        $matches2[1] = substr($matches2[1], 0, $endLength);
                    }
                    $part .= $matches2[1];
                    $end = false;

                } elseif (preg_match('/^[\pL\pN]+/u', $str)) {
                    $value = preg_replace('/[\s]*[\pL\pN]+$/u', '', $part);
                    continue;
                }
            }
            //знак конца предолжения
            elseif (preg_match('/[\.\!\?]+$/u', $checkPart)) {
                if (preg_match('/^([\.\!\?]+)/u', $str, $matches)) {
                    if (strlen($matches[1]) > $endLength) {
                        $matches[1] = substr($matches[1], 0, $endLength);
                    }

                    $part .= $matches[1];
                }
                $end = false;
            }
            //окончание на другие символы
            else {
                $value = preg_replace('/[^\pL\pN\.\!\?]$/u', '', $part);
                continue;
            }

            $value = $part;

            break;

        }

        $value = trim($value);

        if ($end || empty($value)) {
            $value .= $this->_options['end'];
        }

		return $value;
    }

}
